package com.ease.integration.snmp;

import java.io.IOException;
import java.util.Vector;

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class Snmp4jSnmpClient extends SnmpClient {

	public static final String NO_SUCH_OBJECT = "noSuchObject";

	public static final String COMMUNITY = "public";

	private String community;

	private Snmp snmp;

	private CommunityTarget communityTarget;

	public boolean connect() throws RuntimeException {

		if (port < 1) {
			port = PORT;
		}
		if (!notEmpty(community)) {
			community = COMMUNITY;
		}

		try {
			Address targetAddress = GenericAddress.parse("udp:" + host + "/" + port);
			TransportMapping<?> transport = new DefaultUdpTransportMapping();
			snmp = new Snmp(transport);
			transport.listen();

			communityTarget = new CommunityTarget();
			communityTarget.setCommunity(new OctetString("public"));
			communityTarget.setAddress(targetAddress);
			// 通信不成功时的重试次数
			communityTarget.setRetries(2);
			// 超时时间
			communityTarget.setTimeout(5000);
			communityTarget.setVersion(SnmpConstants.version1);

			return true;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public boolean disconnect() throws RuntimeException {
		try {
			snmp.close();
			return true;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 1.3.6.1.4.1.9.9.48.1.1.1 = noSuchObject
	 * 
	 * @param oid
	 * @param result
	 * @throws Exception
	 */
	public String get(String oid) throws RuntimeException {

		PDU request = new PDU();
		request.setType(PDU.GET);
		request.add(new VariableBinding(new OID(oid)));

		try {
			ResponseEvent responseEvent = snmp.send(request, communityTarget);

			if (null == responseEvent) {
				throw new RuntimeException("responseEvent not found");
			}

			PDU response = responseEvent.getResponse();

			if (null != response) {
				if (response.getErrorIndex() == PDU.noError && response.getErrorStatus() == PDU.noError) {

					Vector<? extends VariableBinding> variableBindings = response.getVariableBindings();
					// result = variableBinding.toString().split("=")[1].trim();
					VariableBinding variableBinding = firstOne(variableBindings);
					if (null != variableBinding && null != variableBinding.getVariable()) {
						return variableBinding.getVariable().toString();
					}
				} else {
					throw new RuntimeException(response.getErrorStatusText(), responseEvent.getError());
				}
			} else {
				throw new RuntimeException("response not found", responseEvent.getError());
			}
			return null;
		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (RuntimeException e) {
			throw e;
		}

	}

	/**
	 * @return the community
	 */
	public String getCommunity() {
		return community;
	}

	/**
	 * @param community
	 *            the community to set
	 */
	public void setCommunity(String community) {
		this.community = community;
	}

}
